#ifndef APPLICATION_H
#define APPLICATION_H

#include "Singleton.h"
#include <AntTweakBar.h>
#include <glm/glm.hpp>

class Application: public Singleton<Application>{
private:
	glm::vec3 camera;
	int numOfBoids;
public:
	Application():camera(0, 1.2f, 200.f), numOfBoids(0){}

	void Init();
	void Draw();
	void drawScene(const char* file_name);
	void Update(double h);
	void Run();
	void Destroy();

	void setCameraX(float f){ camera.x = f; }
	void setCameraY(float f){ camera.y = f; }
	void setCameraZ(float f){ camera.z = f; }

	float getCameraX(){ return camera.x; }
	float getCameraY(){ return camera.y; }
	float getCameraZ(){ return camera.z; }

	void setNumOfBoids(int n);
	int getNumOfBoids(){ return numOfBoids; }
	void updateNumOfBoids(){ numOfBoids++; }

	static void TW_CALL setCameraXCallback(const void *value, void *clientData){
		Application::get_Instance()->setCameraX(*static_cast<const float *>(value));
	}
	static void TW_CALL setCameraYCallback(const void *value, void *clientData){
		Application::get_Instance()->setCameraY(*static_cast<const float *>(value));
	}
	static void TW_CALL setCameraZCallback(const void *value, void *clientData){
		Application::get_Instance()->setCameraZ(*static_cast<const float *>(value));
	}

	static void TW_CALL getCameraXCallback(void *value, void *clientData){
		*static_cast<float *>(value) = Application::get_Instance()->getCameraX();
	}
	static void TW_CALL getCameraYCallback(void *value, void *clientData){
		*static_cast<float *>(value) = Application::get_Instance()->getCameraY();
	}
	static void TW_CALL getCameraZCallback(void *value, void *clientData){
		*static_cast<float *>(value) = Application::get_Instance()->getCameraZ();
	}

	static void TW_CALL setNumOfBoidsCallback(const void *value, void *clientData){
		Application::get_Instance()->setNumOfBoids(*static_cast<const int *>(value));
	}
	static void TW_CALL getNumOfBoidsCallback(void *value, void *clientData){
		*static_cast<int *>(value) = Application::get_Instance()->getNumOfBoids();
	}
	
};

#endif